<template>
  <div class="custom-field">
    <!-- 文本框 -->
    <el-input
      v-if="field.type === 'text'"
      v-model="fieldValue"
      :placeholder="field.placeholder"
      :disabled="disabled"
      @input="handleInput"
    />
    
    <!-- 多行文本 -->
    <el-input
      v-else-if="field.type === 'textarea'"
      v-model="fieldValue"
      type="textarea"
      :rows="field.settings?.rows || 3"
      :placeholder="field.placeholder"
      :disabled="disabled"
      @input="handleInput"
    />
    
    <!-- 数字 -->
    <el-input-number
      v-else-if="field.type === 'number'"
      v-model="fieldValue"
      :min="field.validation?.min"
      :max="field.validation?.max"
      :precision="field.settings?.precision || 0"
      :disabled="disabled"
      @change="handleInput"
    />
    
    <!-- 邮箱 -->
    <el-input
      v-else-if="field.type === 'email'"
      v-model="fieldValue"
      type="email"
      :placeholder="field.placeholder"
      :disabled="disabled"
      @input="handleInput"
    />
    
    <!-- URL -->
    <el-input
      v-else-if="field.type === 'url'"
      v-model="fieldValue"
      type="url"
      :placeholder="field.placeholder"
      :disabled="disabled"
      @input="handleInput"
    />
    
    <!-- 日期 -->
    <el-date-picker
      v-else-if="field.type === 'date'"
      v-model="fieldValue"
      type="date"
      :placeholder="field.placeholder"
      :disabled="disabled"
      format="YYYY-MM-DD"
      value-format="YYYY-MM-DD"
      @change="handleInput"
    />
    
    <!-- 日期时间 -->
    <el-date-picker
      v-else-if="field.type === 'datetime'"
      v-model="fieldValue"
      type="datetime"
      :placeholder="field.placeholder"
      :disabled="disabled"
      format="YYYY-MM-DD HH:mm:ss"
      value-format="YYYY-MM-DD HH:mm:ss"
      @change="handleInput"
    />
    
    <!-- 单选框 -->
    <el-radio-group
      v-else-if="field.type === 'radio'"
      v-model="fieldValue"
      :disabled="disabled"
      @change="handleInput"
    >
      <el-radio
        v-for="option in field.options"
        :key="option.value"
        :label="option.value"
      >
        {{ option.label }}
      </el-radio>
    </el-radio-group>
    
    <!-- 复选框 -->
    <el-checkbox-group
      v-else-if="field.type === 'checkbox'"
      v-model="fieldValue"
      :disabled="disabled"
      @change="handleInput"
    >
      <el-checkbox
        v-for="option in field.options"
        :key="option.value"
        :label="option.value"
      >
        {{ option.label }}
      </el-checkbox>
    </el-checkbox-group>
    
    <!-- 下拉选择 -->
    <el-select
      v-else-if="field.type === 'select'"
      v-model="fieldValue"
      :placeholder="field.placeholder"
      :disabled="disabled"
      :multiple="field.settings?.multiple"
      @change="handleInput"
    >
      <el-option
        v-for="option in field.options"
        :key="option.value"
        :label="option.label"
        :value="option.value"
      />
    </el-select>
    
    <!-- 开关 -->
    <el-switch
      v-else-if="field.type === 'switch'"
      v-model="fieldValue"
      :disabled="disabled"
      @change="handleInput"
    />
    
    <!-- 图片 -->
    <div v-else-if="field.type === 'image'" class="image-field">
      <div v-if="fieldValue" class="image-preview">
        <img
          :src="fieldValue"
          :alt="field.label"
          @click="previewImage(fieldValue)"
          style="cursor: pointer;"
        />
        <div class="image-actions">
          <el-button
            size="small"
            :disabled="disabled || uploading"
            @click="selectImage"
          >
            更换
          </el-button>
          <el-button
            size="small"
            type="danger"
            :disabled="disabled"
            @click="removeImage"
          >
            删除
          </el-button>
        </div>
      </div>
      <div
        v-else
        class="image-placeholder"
        :class="{ disabled: disabled }"
        @click="selectImage"
      >
        <el-icon v-if="!uploading"><Plus /></el-icon>
        <el-icon v-else class="is-loading"><Upload /></el-icon>
        <span>{{ uploading ? '上传中...' : '选择图片' }}</span>
      </div>
      <input
        ref="imageInputRef"
        type="file"
        accept="image/*"
        style="display: none"
        @change="handleImageSelect"
      />
    </div>
    
    <!-- 文件 -->
    <div v-else-if="field.type === 'file'" class="file-field">
      <div v-if="fieldValue" class="file-info">
        <el-icon><Document /></el-icon>
        <span class="file-name">{{ getFileName(fieldValue) }}</span>
        <div class="file-actions">
          <el-button
            size="small"
            :disabled="disabled || uploading"
            @click="selectFile"
          >
            更换
          </el-button>
          <el-button
            size="small"
            type="danger"
            :disabled="disabled"
            @click="removeFile"
          >
            删除
          </el-button>
        </div>
      </div>
      <el-button
        v-else
        :disabled="disabled || uploading"
        :loading="uploading"
        @click="selectFile"
      >
        <el-icon v-if="!uploading"><Upload /></el-icon>
        {{ uploading ? '上传中...' : '选择文件' }}
      </el-button>
      <input
        ref="fileInputRef"
        type="file"
        style="display: none"
        @change="handleFileSelect"
      />
    </div>
    
    <!-- 富文本 -->
    <div v-else-if="field.type === 'editor'" class="editor-field">
      <div ref="editorRef" class="editor-container"></div>
    </div>
    
    <!-- 标签 -->
    <el-select
      v-else-if="field.type === 'tags'"
      v-model="fieldValue"
      multiple
      filterable
      allow-create
      default-first-option
      :placeholder="field.placeholder"
      :disabled="disabled"
      @change="handleInput"
    >
      <el-option
        v-for="tag in predefinedTags"
        :key="tag"
        :label="tag"
        :value="tag"
      />
    </el-select>
    
    <!-- 默认文本框 -->
    <el-input
      v-else
      v-model="fieldValue"
      :placeholder="field.placeholder"
      :disabled="disabled"
      @input="handleInput"
    />
  </div>
</template>

<script setup lang="ts">
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Document, Upload, Delete } from '@element-plus/icons-vue'

// 临时类型定义（避免导入问题）
interface ModelField {
  name: string
  label: string
  type: string
  required?: boolean
  defaultValue?: any
  placeholder?: string
  options?: { value: string; label: string }[]
  validation?: Record<string, any>
  settings?: Record<string, any>
}

interface Attachment {
  id: number
  url: string
  name: string
  size: number
}

// 简化的验证函数
const validateImageFile = (file: File) => {
  const allowedTypes = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']
  const extension = file.name.split('.').pop()?.toLowerCase() || ''

  if (!allowedTypes.includes(extension)) {
    return { valid: false, error: `不支持的图片格式：${extension}` }
  }

  if (file.size > 10 * 1024 * 1024) {
    return { valid: false, error: '图片大小不能超过10MB' }
  }

  return { valid: true }
}

const validateGeneralFile = (file: File) => {
  if (file.size > 100 * 1024 * 1024) {
    return { valid: false, error: '文件大小不能超过100MB' }
  }

  return { valid: true }
}

// 简化的store
const userStore = {
  userId: ref(1) // 模拟用户ID
}

const siteStore = {
  currentSiteId: ref(1) // 模拟站点ID
}

// 简化的API
const attachmentApi = {
  async uploadFile(file: File, siteId: number, userId: number) {
    // 模拟上传
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve({
          code: 0,
          data: {
            url: URL.createObjectURL(file),
            name: file.name,
            size: file.size
          }
        })
      }, 1000)
    })
  }
}

interface Props {
  field: ModelField
  modelValue?: any
  disabled?: boolean
}

interface Emits {
  (e: 'update:modelValue', value: any): void
  (e: 'change', value: any): void
}

const props = withDefaults(defineProps<Props>(), {
  disabled: false,
})

const emit = defineEmits<Emits>()

const editorRef = ref<HTMLElement>()
const fileInputRef = ref<HTMLInputElement>()
const imageInputRef = ref<HTMLInputElement>()
const predefinedTags = ref<string[]>([])
const uploading = ref(false)

// 字段值
const fieldValue = computed({
  get() {
    return props.modelValue
  },
  set(value) {
    emit('update:modelValue', value)
    emit('change', value)
  },
})

// 富文本编辑器实例
let editor: any = null

// 处理输入
const handleInput = (value: any) => {
  emit('update:modelValue', value)
  emit('change', value)
}

// 验证字段值
const validateField = (value: any): boolean => {
  if (props.field.required && (!value || value === '')) {
    ElMessage.error(`${props.field.label}不能为空`)
    return false
  }

  // 数字类型验证
  if (props.field.type === 'number' && props.field.validation) {
    const num = Number(value)
    if (props.field.validation.min !== undefined && num < props.field.validation.min) {
      ElMessage.error(`${props.field.label}不能小于${props.field.validation.min}`)
      return false
    }
    if (props.field.validation.max !== undefined && num > props.field.validation.max) {
      ElMessage.error(`${props.field.label}不能大于${props.field.validation.max}`)
      return false
    }
  }

  // 字符串长度验证
  if (typeof value === 'string' && props.field.validation) {
    if (props.field.validation.minLength && value.length < props.field.validation.minLength) {
      ElMessage.error(`${props.field.label}长度不能少于${props.field.validation.minLength}个字符`)
      return false
    }
    if (props.field.validation.maxLength && value.length > props.field.validation.maxLength) {
      ElMessage.error(`${props.field.label}长度不能超过${props.field.validation.maxLength}个字符`)
      return false
    }
  }

  return true
}

// 选择图片
const selectImage = () => {
  if (props.disabled) return

  if (!imageInputRef.value) {
    const input = document.createElement('input')
    input.type = 'file'
    input.accept = 'image/*'
    input.onchange = handleImageSelect
    input.click()
  } else {
    imageInputRef.value.click()
  }
}

// 处理图片选择
const handleImageSelect = async (event: Event) => {
  const target = event.target as HTMLInputElement
  const file = target.files?.[0]

  if (!file) return

  // 验证图片文件
  const validation = validateImageFile(file)
  if (!validation.valid) {
    ElMessage.error(validation.error!)
    return
  }

  await uploadFile(file, 'image')
}

// 选择文件
const selectFile = () => {
  if (props.disabled) return

  if (!fileInputRef.value) {
    const input = document.createElement('input')
    input.type = 'file'
    input.onchange = handleFileSelect
    input.click()
  } else {
    fileInputRef.value.click()
  }
}

// 处理文件选择
const handleFileSelect = async (event: Event) => {
  const target = event.target as HTMLInputElement
  const file = target.files?.[0]

  if (!file) return

  // 验证文件
  const validation = validateGeneralFile(file)
  if (!validation.valid) {
    ElMessage.error(validation.error!)
    return
  }

  await uploadFile(file, 'file')
}

// 上传文件
const uploadFile = async (file: File, _type: 'image' | 'file') => {
  if (!userStore.userId || !siteStore.currentSiteId) {
    ElMessage.error('用户信息或站点信息缺失')
    return
  }

  uploading.value = true

  try {
    const response = await attachmentApi.uploadFile(
      file,
      Number(siteStore.currentSiteId),
      Number(userStore.userId)
    ) as any

    if (response.code === 0 && response.data) {
      fieldValue.value = response.data.url
      ElMessage.success('上传成功')
    } else {
      ElMessage.error(response.message || '上传失败')
    }
  } catch (error) {
    console.error('上传失败:', error)
    ElMessage.error('上传失败，请重试')
  } finally {
    uploading.value = false
  }
}

// 删除图片
const removeImage = async () => {
  if (props.disabled) return

  try {
    await ElMessageBox.confirm('确定要删除这张图片吗？', '确认删除', {
      type: 'warning'
    })
    fieldValue.value = ''
    ElMessage.success('删除成功')
  } catch {
    // 用户取消删除
  }
}

// 删除文件
const removeFile = async () => {
  if (props.disabled) return

  try {
    await ElMessageBox.confirm('确定要删除这个文件吗？', '确认删除', {
      type: 'warning'
    })
    fieldValue.value = ''
    ElMessage.success('删除成功')
  } catch {
    // 用户取消删除
  }
}

// 获取文件名
const getFileName = (url: string) => {
  if (!url) return ''
  return url.split('/').pop() || url
}

// 预览图片
const previewImage = (url: string) => {
  if (!url) return

  // 创建预览窗口
  const img = new Image()
  img.src = url
  img.style.maxWidth = '100%'
  img.style.maxHeight = '100%'

  const div = document.createElement('div')
  div.style.position = 'fixed'
  div.style.top = '0'
  div.style.left = '0'
  div.style.width = '100%'
  div.style.height = '100%'
  div.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'
  div.style.display = 'flex'
  div.style.alignItems = 'center'
  div.style.justifyContent = 'center'
  div.style.zIndex = '9999'
  div.style.cursor = 'pointer'

  div.appendChild(img)
  div.onclick = () => document.body.removeChild(div)

  document.body.appendChild(div)
}

// 初始化富文本编辑器
const initEditor = async () => {
  if (props.field.type !== 'editor' || !editorRef.value) {
    return
  }

  try {
    // 动态导入编辑器
    const { createEditor } = await import('@wangeditor/editor')

    editor = createEditor({
      selector: editorRef.value,
      html: fieldValue.value || '',
      config: {
        placeholder: props.field.placeholder || '请输入内容...',
        readOnly: props.disabled,
        onChange(editor: any) {
          const html = editor.getHtml()
          fieldValue.value = html
        },
        MENU_CONF: {
          uploadImage: {
            server: '/api/admin/attachment/upload',
            fieldName: 'file',
            maxFileSize: 10 * 1024 * 1024, // 10MB
            allowedFileTypes: ['image/*'],
            customInsert(res: any, insertFn: any) {
              if (res.code === 0 && res.data) {
                insertFn(res.data.url, res.data.name, res.data.url)
              } else {
                ElMessage.error(res.message || '图片上传失败')
              }
            },
            onError(_file: File, err: any, res: any) {
              console.error('图片上传失败:', err, res)
              ElMessage.error('图片上传失败')
            }
          },
          uploadVideo: {
            server: '/api/admin/attachment/upload',
            fieldName: 'file',
            maxFileSize: 100 * 1024 * 1024, // 100MB
            allowedFileTypes: ['video/*'],
            customInsert(res: any, insertFn: any) {
              if (res.code === 0 && res.data) {
                insertFn(res.data.url)
              } else {
                ElMessage.error(res.message || '视频上传失败')
              }
            },
            onError(_file: File, err: any, res: any) {
              console.error('视频上传失败:', err, res)
              ElMessage.error('视频上传失败')
            }
          }
        },
      },
    })
  } catch (error) {
    console.error('初始化富文本编辑器失败:', error)
    ElMessage.error('富文本编辑器初始化失败')
  }
}

// 销毁富文本编辑器
const destroyEditor = () => {
  if (editor) {
    try {
      editor.destroy()
      editor = null
    } catch (error) {
      console.error('销毁富文本编辑器失败:', error)
    }
  }
}

// 获取预定义标签
const getPredefinedTags = async () => {
  if (props.field.type !== 'tags') {
    return
  }

  try {
    // 从字段设置中获取预定义标签
    if (props.field.settings?.predefinedTags) {
      predefinedTags.value = props.field.settings.predefinedTags
    } else {
      // 默认标签
      predefinedTags.value = [
        '前端', '后端', '数据库', '运维', '设计',
        '开发', '测试', '产品', '运营', '市场'
      ]
    }
  } catch (error) {
    console.error('获取预定义标签失败:', error)
    predefinedTags.value = []
  }
}

// 暴露验证方法给父组件
const validate = (): boolean => {
  return validateField(fieldValue.value)
}

// 暴露重置方法给父组件
const reset = () => {
  fieldValue.value = props.field.defaultValue || ''
}

// 暴露获取值方法给父组件
const getValue = () => {
  return fieldValue.value
}

// 暴露设置值方法给父组件
const setValue = (value: any) => {
  fieldValue.value = value
}

// 暴露方法给父组件使用
defineExpose({
  validate,
  reset,
  getValue,
  setValue
})

// 监听字段类型变化
watch(
  () => props.field.type,
  async (newType) => {
    if (newType === 'editor') {
      await nextTick()
      initEditor()
    } else if (newType === 'tags') {
      getPredefinedTags()
    }
  },
  { immediate: true }
)

// 监听字段值变化（用于富文本编辑器）
watch(
  () => props.modelValue,
  (newValue) => {
    if (props.field.type === 'editor' && editor && newValue !== editor.getHtml()) {
      editor.setHtml(newValue || '')
    }
  }
)

onMounted(() => {
  // 初始化字段默认值
  if (fieldValue.value === undefined || fieldValue.value === null) {
    if (props.field.defaultValue !== undefined) {
      fieldValue.value = props.field.defaultValue
    } else {
      // 根据字段类型设置默认值
      switch (props.field.type) {
        case 'checkbox':
        case 'tags':
          fieldValue.value = []
          break
        case 'switch':
          fieldValue.value = false
          break
        case 'number':
          fieldValue.value = 0
          break
        default:
          fieldValue.value = ''
      }
    }
  }

  // 初始化特定类型的字段
  if (props.field.type === 'editor') {
    nextTick(() => {
      initEditor()
    })
  } else if (props.field.type === 'tags') {
    getPredefinedTags()
  }
})

onUnmounted(() => {
  destroyEditor()
})
</script>

<style scoped lang="scss">
.custom-field {
  width: 100%;
  
  .image-field {
    .image-preview {
      position: relative;
      display: inline-block;
      
      img {
        max-width: 200px;
        max-height: 150px;
        border-radius: 4px;
        border: 1px solid #dcdfe6;
      }
      
      .image-actions {
        position: absolute;
        top: 8px;
        right: 8px;
        display: flex;
        gap: 4px;
      }
    }
    
    .image-placeholder {
      width: 200px;
      height: 150px;
      border: 2px dashed #dcdfe6;
      border-radius: 4px;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      cursor: pointer;
      color: #c0c4cc;
      transition: all 0.3s ease;

      &:hover:not(.disabled) {
        border-color: #409eff;
        color: #409eff;
      }

      &.disabled {
        cursor: not-allowed;
        opacity: 0.6;
      }

      .el-icon {
        font-size: 24px;
        margin-bottom: 8px;

        &.is-loading {
          animation: rotating 2s linear infinite;
        }
      }

      span {
        font-size: 14px;
      }
    }
  }
  
  .file-field {
    .file-info {
      display: flex;
      align-items: center;
      gap: 8px;
      padding: 8px 12px;
      border: 1px solid #dcdfe6;
      border-radius: 4px;
      background-color: #f5f7fa;

      .file-name {
        flex: 1;
        color: #606266;
        font-size: 14px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      .file-actions {
        display: flex;
        gap: 4px;
      }
    }
  }
  
  .editor-field {
    .editor-container {
      min-height: 300px;
      border: 1px solid #dcdfe6;
      border-radius: 4px;
      overflow: hidden;
    }
  }

  // 验证错误状态
  &.has-error {
    .el-input,
    .el-textarea,
    .el-select,
    .el-date-picker,
    .image-placeholder,
    .file-info,
    .editor-container {
      border-color: #f56c6c !important;
    }
  }

  // 禁用状态
  &.is-disabled {
    opacity: 0.6;
    pointer-events: none;
  }

  // 加载状态
  &.is-loading {
    position: relative;

    &::after {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: rgba(255, 255, 255, 0.8);
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 10;
    }
  }
}

// 旋转动画
@keyframes rotating {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

// 响应式设计
@media (max-width: 768px) {
  .custom-field {
    .image-field {
      .image-preview {
        img {
          max-width: 150px;
          max-height: 100px;
        }
      }

      .image-placeholder {
        width: 150px;
        height: 100px;
      }
    }
  }
}
</style>
